import React, { useRef, useState, useEffect } from "react";
import styles from "./index.module.less";
import { connect } from "react-redux";
import { selectEmojiInfo, recordCurrentRange } from "@redux/actions02";
import { Scrollbars } from "react-custom-scrollbars-2";

let currentRange;

const InputMain = (props) => {
    const { /* emojiInfo, */ recordCurrentRange } = props;

    const main = useRef();
    const pas = useRef();
    const editWrap = useRef();
    const edit = useRef();
    const [isShowPaste, setIsShowPaste] = useState(false);

    const wrapOper = () => {
        const selection = window.getSelection();
        if (currentRange) {
            selection.removeAllRanges();
            selection.addRange(currentRange);
        } else {
            selection.selectAllChildren(edit.current);
            selection.collapseToEnd();
        }
    };

    const editOper = () => {
        const selection = window.getSelection();
        currentRange = selection.getRangeAt(0);
        recordCurrentRange(currentRange);
    };

    useEffect(() => {
        document.documentElement.onclick = function () {
            setIsShowPaste(false);
        };
        document.documentElement.onkeydown = function () {
            setIsShowPaste(false);
        };
    }, []);

    useEffect(() => {
        // Enter发送 Shift + Enter下一行
        document.onkeydown = function (e) {
            // 当按键是Enter键且没有同时按shift键且输入框获取了焦点
            if (
                e.key === "Enter" &&
                !e.shiftKey &&
                edit.current === document.activeElement
            ) {
                e.preventDefault();
            }
        };
    }, []);

    const handlePaste = (e) => {
        const paste = e.clipboardData || window.clipboardData;
        for (let i = 0; i < paste.items.length; i++) {
            if (paste.items[i].type === "text/html") {
                // 如果是text/html类型的粘贴内容，就阻止默认粘贴，然后修改粘贴方法
                e.preventDefault();
                // 重写要被粘贴的内容
                paste.items[i].getAsString((data) => {
                    // 这里用选区来设置粘贴时光标的位置
                    const selection = window.getSelection();
                    const range = selection.getRangeAt(0);
                    const span = document.createElement("span");
                    /**
                     * 正则处理
                     * (style=").*?;" 清除样式
                     * ((<a).*?>)|(<\/a>) 清除a标签，只保留a标签中的文本内容
                     * ((<span).*?>)|(<\/span>) 去掉多余的span标签
                     */
                    span.innerHTML = data.replace(
                        /((style=").*?;")|((<a).*?>)|(<\/a>)|((<span).*?>)|(<\/span>)/g,
                        ""
                    );
                    range.insertNode(span);
                    range.collapse();
                    selection.removeAllRanges();
                    selection.addRange(range);
                });
            } else if (paste.items[i].type.includes("image/")) {
                paste.items[i].getAsFile((data) => {
                    console.log("file: ", data);
                });
            }
        }
    };

    useEffect(() => {
        /**
         * 重写ctrl + v粘贴方法，目的是在黏贴前修改被粘贴的内容
         */
        edit.current.onpaste = function (e) {
            handlePaste(e);
        };
    }, []);

    return (
        <div
            className={styles.input_main}
            ref={main}
            onContextMenu={(e) => {
                e.preventDefault();
                const x = e.clientX;
                const y = e.clientY;
                pas.current.style.top = y + 3 + "px";
                pas.current.style.left = x + 3 + "px";
                setIsShowPaste(true);
            }}
            onClick={() => {
                setIsShowPaste(false);
            }}
        >
            <div
                className={styles.edit_wrap}
                ref={editWrap}
                onClick={wrapOper}
                onContextMenu={wrapOper} // 右击也要让edit编辑区获取到焦点
            >
                <Scrollbars autoHide>
                    <div
                        className={styles.edit}
                        contentEditable
                        ref={edit}
                        onClick={editOper}
                        onKeyUp={editOper}
                    ></div>
                </Scrollbars>
            </div>
            <p
                className={styles.paste_btn}
                ref={pas}
                style={{ display: isShowPaste ? "block" : "none" }}
                onClick={async () => {
                    // 点击粘贴按钮完成粘贴功能

                    const clip = window.navigator.clipboard;
                    const items = await clip.read();
                    let pasteContent;
                    for (const item of items) {
                        for (const type of item.types) {
                            const blob = await item.getType(type);
                            const result = await blob.text();

                            if (type === "text/plain") {
                                pasteContent = result;
                            } else if (type === "text/html") {
                                pasteContent = result.replace(
                                    /((style=").*?;")|((<a).*?>)|(<\/a>)|((<span).*?>)|(<\/span>)/g,
                                    ""
                                );
                            } else if (type.includes("image/")) {
                                // 这里需要注意，src不能直接使用result结果，必须用URL的方法进行转换成blob地址
                                // 不然会乱码，无法正常显示图片
                                pasteContent = `<img src=${URL.createObjectURL(
                                    blob
                                )} >`;
                            }
                        }
                    }
                    // 把内容放入可编辑选区
                    const selection = window.getSelection();
                    const range = selection.getRangeAt(0);
                    const span = document.createElement("span");
                    span.innerHTML = pasteContent;
                    range.insertNode(span);
                    range.collapse();
                    selection.removeAllRanges();
                    selection.addRange(range);
                }}
            >
                粘贴
            </p>
        </div>
    );
};

export default connect(
    (state) => ({
        emojiInfo: state.emojiInfoReducer,
    }),
    { selectEmojiInfo, recordCurrentRange }
)(InputMain);
